package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.bean.AddressBook;
import com.itheima.bean.OrderDetail;
import com.itheima.bean.Orders;
import com.itheima.bean.ShoppingCart;
import com.itheima.common.OrderStatus;
import com.itheima.common.PageParam;
import com.itheima.dao.OrderDao;
import com.itheima.service.*;
import com.itheima.utils.BaseContext;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

@Service
@Transactional
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private UserService userService;

    /**
     * 添加订单
     *  1. 添加订单其实即使做添加工作，但是要涉及到两张表： 订单表 [orders] 和 订单详情表[order_detail]
     *
     *  2. 在订单表存储订单本身的说明信息，但是订单买的是什么商品，应该要放到订单详情表里面。
     *
     *  3. 添加两张表的时候，先后顺序是有说明的： 订单表 在前  , 订单详情表 在后
     *      3.1 因为只有当订单表现执行添加操作之后，才能获取到订单的id值。
     *      3.2 有了id值之后，就可以往订单详情表里面添加数据。否则就不知道这个订单详情属于哪一个订单的数据。
     *
     * @param orders
     * @return
     */
    @Override
    public int add(Orders orders) {

        //1.1 准备订单数据
        initOrders(orders);

        //1.2 执行添加
        int row = orderDao.insert(orders);

        if(row > 0 ){
            //2. 添加到订单详情表
            //2.1 订单详情表的数据是来自于购物车的数据，所以要先把当前用户的购物车数据查询出来
            List<ShoppingCart> cartList = shoppingCartService.findByUid(BaseContext.getCurrentId());

            int row2 = 0 ;
            //2.2 遍历购物车集合，购物车集合里面的每一件菜品|套餐，就是一条订单详情数据
            for (ShoppingCart cart : cartList) {

                //2.3 构建订单详情对象，然后组装数据
                OrderDetail orderDetail = new OrderDetail();

                //2.4 组装购物车数据
                BeanUtils.copyProperties(cart ,orderDetail);

                //2.5 设置属于哪一个订单
                orderDetail.setOrderId(orders.getId());

                //2.6 执行添加
                row2 += orderDetailService.add(orderDetail);
            }

            return row2 == cartList.size() ? 1 : 0 ;
        }


        return row;
    }

    @Override
    public IPage<Orders> findHistoryOrder(Integer page1, Integer pageSize) {
        IPage<Orders> page = new Page<>(page1,pageSize);

        return orderDao.selectPage(page,new LambdaQueryWrapper<Orders>());
    }

    /**
     * 订单分页查询
     * @param pageParam
     * @return
     */
    @Override
    public IPage<Orders> findPage(PageParam pageParam) {
        //构建IPage分页对象，设置条件
        IPage<Orders> page = new Page<>(pageParam.getPage(),pageParam.getPageSize());
        //构建条件查询对象
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        //设置条件
        wrapper.ge(StringUtils.isNotEmpty(pageParam.getBeginTime()),Orders::getOrderTime,pageParam.getBeginTime())
                .le(StringUtils.isNotEmpty(pageParam.getEndTime()),Orders::getCheckoutTime,pageParam.getEndTime())
                .like(StringUtils.isNotEmpty(pageParam.getNumber()),Orders::getNumber,pageParam.getNumber());
        //执行条件
        return orderDao.selectPage(page, wrapper);
    }

    /**
     * 修改状态为已派送
     *
     * @param orders
     * @return
     */
    @Override
    public int updateStatus(OrderStatus orders) {

        Orders one = orderDao.selectById(orders.getId());

        int row=0;

        if (one != null) {

            one.setStatus(orders.getStatus());

             row = orderDao.updateById(one);
        }

        return row;
    }

    /**
     * 补充订单数据
     * @param orders
     */
    private void initOrders(Orders orders) {
        //1. 添加到订单表
        //1.1 补充数据
        //1.1.1 补充订单编号 number
        orders.setNumber(UUID.randomUUID().toString().replace("-",""));
        //1.1.2 补充状态值
        orders.setStatus(1);
        //1.1.3 补充用户id
        orders.setUserId(BaseContext.getCurrentId());
        //1.1.4 补充地址簿id::不需要设置，页面有提交
        //1.1.5 补充下单时间
        orders.setOrderTime(LocalDateTime.now());
        //1.1.6 补充支付时间
        orders.setCheckoutTime(LocalDateTime.now());
        //1.1.7 补充支付方式::不需要设置，页面有提交
        //TODO:: 1.1.8 补充订单的总价::不需要设置，页面有提交
        //1.1.9 补充订单备注::不需要设置，页面有提交

        AddressBook addressBook = addressBookService.getById(orders.getAddressBookId());
        //1.1.10 补充收件人电话
        orders.setPhone(addressBook.getPhone());
        //1.1.11 补充收件人地址
        String address =
                (addressBook.getProvinceName() != null ? addressBook.getProvinceName() : "")+
                (addressBook.getCityName() != null ? addressBook.getCityName() : "")+
                (addressBook.getDistrictName() != null ? addressBook.getDistrictName() : "")+
                (addressBook.getDetail() != null ? addressBook.getDetail() : "");
        orders.setAddress(address);
        //1.1.12 补充下单的用户名字
        orders.setUserName(userService.findByUid(BaseContext.getCurrentId()).getName());
        //1.1.13 补充收件人的名字
        orders.setConsignee(addressBook.getConsignee());
    }


    /**
     * 用户订单分页查询
     *
     * @param pageParam
     * @Description
     * @Return
     */
    @Override
    public IPage<Orders> userPage(PageParam pageParam) {
        IPage<Orders> page = new Page<>(pageParam.getPage() , pageParam.getPageSize());

        LambdaQueryWrapper<Orders> lqw = new LambdaQueryWrapper<>();

        IPage<Orders> ordersIPage = orderDao.selectPage(page, lqw);

        return ordersIPage;
    }

}
